/****************************************************
	文件：EventCenter.cs
	作者：HuskyT
	邮箱：1005240602@qq.com
	日期：2020/10/11 10:57:59
	功能：事件中心
*****************************************************/

using System;
using System.Collections.Generic;

namespace HTUtility
{
    public class EventCenter
    {
        #region 事件缓存
        private static Dictionary<EventType, Delegate> mEventDict = new Dictionary<EventType, Delegate>();
        #endregion

        #region public（对外开放的API）
        /// <summary>
        /// 注册事件
        /// （参数数组）
        /// </summary>
        public static void Subscribe(EventType eventType, HTCallBack callBack)
        {
            BeforeSubscribe(eventType, callBack);
            //多播委托(顺序遍历，返回最后一个委托的返回值)
            mEventDict[eventType] = (HTCallBack)mEventDict[eventType] + callBack;
        }
        /// <summary>
        /// 注册事件
        /// （0个参数）
        /// </summary>
        public static void Subscribe(EventType eventType, HTEvent callBack)
        {
            BeforeSubscribe(eventType, callBack);
            //多播委托(顺序遍历，返回最后一个委托的返回值)
            mEventDict[eventType] = (HTEvent)mEventDict[eventType] + callBack;
        }
        /// <summary>
        /// 注册事件
        /// （1个参数）
        /// </summary>
        public static void Subscribe<T>(EventType eventType, HTEvent<T> callBack)
        {
            BeforeSubscribe(eventType, callBack);
            //多播委托(顺序遍历，返回最后一个委托的返回值)
            mEventDict[eventType] = (HTEvent<T>)mEventDict[eventType] + callBack;
        }
        /// <summary>
        /// 注册事件
        /// （2个参数）
        /// </summary>
        public static void Subscribe<T, X>(EventType eventType, HTEvent<T, X> callBack)
        {
            BeforeSubscribe(eventType, callBack);
            //多播委托(顺序遍历，返回最后一个委托的返回值)
            mEventDict[eventType] = (HTEvent<T, X>)mEventDict[eventType] + callBack;
        }
        /// <summary>
        /// 注册事件
        /// （3个参数）
        /// </summary>
        public static void Subscribe<T, X, Y>(EventType eventType, HTEvent<T, X, Y> callBack)
        {
            BeforeSubscribe(eventType, callBack);
            //多播委托(顺序遍历，返回最后一个委托的返回值)
            mEventDict[eventType] = (HTEvent<T, X, Y>)mEventDict[eventType] + callBack;
        }
        /// <summary>
        /// 注册事件
        /// （4个参数）
        /// </summary>
        public static void Subscribe<T, X, Y, Z>(EventType eventType, HTEvent<T, X, Y, Z> callBack)
        {
            BeforeSubscribe(eventType, callBack);
            //多播委托(顺序遍历，返回最后一个委托的返回值)
            mEventDict[eventType] = (HTEvent<T, X, Y, Z>)mEventDict[eventType] + callBack;
        }
        /// <summary>
        /// 注册事件
        /// （5个参数）
        /// </summary>
        public static void Subscribe<T, X, Y, Z, W>(EventType eventType, HTEvent<T, X, Y, Z, W> callBack)
        {
            BeforeSubscribe(eventType, callBack);
            //多播委托(顺序遍历，返回最后一个委托的返回值)
            mEventDict[eventType] = (HTEvent<T, X, Y, Z, W>)mEventDict[eventType] + callBack;
        }

        /// <summary>
        /// 注销事件
        /// （参数数组）
        /// </summary>
        public static void Unsubscribe(EventType eventType, HTCallBack callBack)
        {
            BeforeUnsubscribe(eventType, callBack);
            mEventDict[eventType] = (HTCallBack)mEventDict[eventType] - callBack;
            AfterUnsubscribe(eventType);
        }
        /// <summary>
        /// 注销事件
        /// （0个参数）
        /// </summary>
        public static void Unsubscribe(EventType eventType, HTEvent callBack)
        {
            BeforeUnsubscribe(eventType, callBack);
            mEventDict[eventType] = (HTEvent)mEventDict[eventType] - callBack;
            AfterUnsubscribe(eventType);
        }
        /// <summary>
        /// 注销事件
        /// （1个参数）
        /// </summary>
        public static void Unsubscribe<T>(EventType eventType, HTEvent<T> callBack)
        {
            BeforeUnsubscribe(eventType, callBack);
            mEventDict[eventType] = (HTEvent<T>)mEventDict[eventType] - callBack;
            AfterUnsubscribe(eventType);
        }
        /// <summary>
        /// 注销事件
        /// （2个参数）
        /// </summary>
        public static void Unsubscribe<T, X>(EventType eventType, HTEvent<T, X> callBack)
        {
            BeforeUnsubscribe(eventType, callBack);
            mEventDict[eventType] = (HTEvent<T, X>)mEventDict[eventType] - callBack;
            AfterUnsubscribe(eventType);
        }
        /// <summary>
        /// 注销事件
        /// （3个参数）
        /// </summary>
        public static void Unsubscribe<T, X, Y>(EventType eventType, HTEvent<T, X, Y> callBack)
        {
            BeforeUnsubscribe(eventType, callBack);
            mEventDict[eventType] = (HTEvent<T, X, Y>)mEventDict[eventType] - callBack;
            AfterUnsubscribe(eventType);
        }
        /// <summary>
        /// 注销事件
        /// （4个参数）
        /// </summary>
        public static void Unsubscribe<T, X, Y, Z>(EventType eventType, HTEvent<T, X, Y, Z> callBack)
        {
            BeforeUnsubscribe(eventType, callBack);
            mEventDict[eventType] = (HTEvent<T, X, Y, Z>)mEventDict[eventType] - callBack;
            AfterUnsubscribe(eventType);
        }
        /// <summary>
        /// 注销事件
        /// （5个参数）
        /// </summary>
        public static void Unsubscribe<T, X, Y, Z, W>(EventType eventType, HTEvent<T, X, Y, Z, W> callBack)
        {
            BeforeUnsubscribe(eventType, callBack);
            mEventDict[eventType] = (HTEvent<T, X, Y, Z, W>)mEventDict[eventType] - callBack;
            AfterUnsubscribe(eventType);
        }

        /// <summary>
        /// 发送消息
        /// （参数数组）
        /// </summary>
        public static void Fire(EventType eventType, params object[] p)
        {
            Delegate d;
            if (mEventDict.TryGetValue(eventType, out d))
            {
                HTCallBack callBack = d as HTCallBack;
                if (callBack != null)
                {
                    callBack(p);
                }
                else
                {
                    HTLogger.Error("发送消息出错！事件{0}对应的委托有不同的类型", eventType);
                }
            }
        }
        /// <summary>
        /// 发送消息
        /// （0个参数）
        /// </summary>
        public static void Fire(EventType eventType)
        {
            Delegate d;
            if (mEventDict.TryGetValue(eventType, out d))
            {
                HTEvent callBack = d as HTEvent;
                if (callBack != null)
                {
                    callBack();
                }
                else
                {
                    HTLogger.Error("发送消息出错！事件{0}对应的委托有不同的类型", eventType);
                }
            }
        }
        /// <summary>
        /// 发送消息
        /// （1个参数）
        /// </summary>
        public static void Fire<T>(EventType eventType, T arg)
        {
            Delegate d;
            if (mEventDict.TryGetValue(eventType, out d))
            {
                HTEvent<T> callBack = d as HTEvent<T>;
                if (callBack != null)
                {
                    callBack(arg);
                }
                else
                {
                    HTLogger.Error("发送消息出错！事件{0}对应的委托有不同的类型", eventType);
                }
            }
        }
        /// <summary>
        /// 发送消息
        /// （2个参数）
        /// </summary>
        public static void Fire<T, X>(EventType eventType, T arg1, X arg2)
        {
            Delegate d;
            if (mEventDict.TryGetValue(eventType, out d))
            {
                HTEvent<T, X> callBack = d as HTEvent<T, X>;
                if (callBack != null)
                {
                    callBack(arg1, arg2);
                }
                else
                {
                    HTLogger.Error("发送消息出错！事件{0}对应的委托有不同的类型", eventType);
                }
            }
        }
        /// <summary>
        /// 发送消息
        /// （3个参数）
        /// </summary>
        public static void Fire<T, X, Y>(EventType eventType, T arg1, X arg2, Y arg3)
        {
            Delegate d;
            if (mEventDict.TryGetValue(eventType, out d))
            {
                HTEvent<T, X, Y> callBack = d as HTEvent<T, X, Y>;
                if (callBack != null)
                {
                    callBack(arg1, arg2, arg3);
                }
                else
                {
                    HTLogger.Error("发送消息出错！事件{0}对应的委托有不同的类型", eventType);
                }
            }
        }
        /// <summary>
        /// 发送消息
        /// （4个参数）
        /// </summary>
        public static void Fire<T, X, Y, Z>(EventType eventType, T arg1, X arg2, Y arg3, Z arg4)
        {
            Delegate d;
            if (mEventDict.TryGetValue(eventType, out d))
            {
                HTEvent<T, X, Y, Z> callBack = d as HTEvent<T, X, Y, Z>;
                if (callBack != null)
                {
                    callBack(arg1, arg2, arg3, arg4);
                }
                else
                {
                    HTLogger.Error("发送消息出错！事件{0}对应的委托有不同的类型", eventType);
                }
            }
        }
        /// <summary>
        /// 发送消息
        /// （5个参数）
        /// </summary>
        public static void Fire<T, X, Y, Z, W>(EventType eventType, T arg1, X arg2, Y arg3, Z arg4, W arg5)
        {
            Delegate d;
            if (mEventDict.TryGetValue(eventType, out d))
            {
                HTEvent<T, X, Y, Z, W> callBack = d as HTEvent<T, X, Y, Z, W>;
                if (callBack != null)
                {
                    callBack(arg1, arg2, arg3, arg4, arg5);
                }
                else
                {
                    HTLogger.Error("发送消息出错！事件{0}对应的委托有不同的类型", eventType);
                }
            }
        }
        #endregion

        #region private（Function）
        /// <summary>
        /// 注册事件之前的安全检验
        /// </summary>
        private static void BeforeSubscribe(EventType eventType, Delegate callBack)
        {
            if (!mEventDict.ContainsKey(eventType))
            {
                mEventDict.Add(eventType, null);
            }
            Delegate d = mEventDict[eventType];
            if (d != null && d.GetType() != callBack.GetType())
            {
                HTLogger.Error("注册事件错误！尝试为事件{0}添加不同类型的委托，当前事件所对应的委托是{1}，要添加的委托类型为{2}", eventType, d.GetType(), callBack.GetType());
            }
        }
        /// <summary>
        /// 注销事件之前的安全检测
        /// </summary>
        private static void BeforeUnsubscribe(EventType eventType, Delegate callBack)
        {
            if (!mEventDict.ContainsKey(eventType))
            {
                HTLogger.Error("注销事件出错！缓存中没有事件码：{0}", eventType);
            }
            else
            {
                Delegate d = mEventDict[eventType];
                if (d == null)
                {
                    HTLogger.Error("注销事件出错！事件{0}没有对应的委托", eventType);
                }
                else if (d.GetType() != callBack.GetType())
                {
                    HTLogger.Error("注销事件出错！尝试为事件{0}添加不同类型的委托，当前事件所对应的委托是{1}，要添加的委托类型为{2}", eventType, d.GetType(), callBack.GetType());
                }
            }
        }
        /// <summary>
        /// 注销事件之后
        /// </summary>
        private static void AfterUnsubscribe(EventType eventType)
        {
            if (mEventDict[eventType] == null)
            {
                mEventDict.Remove(eventType);
            }
        }
        #endregion
    }
}
